package com.bdf.congcache.utils.struct;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

@SuppressWarnings(
{ "unchecked", "rawtypes" })
/**
 * @Author 田培融
 * @Description  双向整体链表
 * @Date 15:24 2019/7/12
 **/
public class DoubleLinkedList<T extends DoubleLinkedListNode>
{
	private static final Log log = LogFactory.getLog(DoubleLinkedList.class);

	private int size = 0;

	private T first;

	private T last;

	public DoubleLinkedList()
	{
		super();
	}

	/**
	 * @description: 将结点添加到链表的第一位置
	 * @author: 田培融
	 * @date: 2019/7/31 9:19
	  * @param me	结点
	 * @return: void
	 */
	public synchronized void addFirst(T me)
	{
		// 第一次添加，last指针为null，将last 指针批向me结点
		if (last == null)
		{
			last = me;
		}
		else//不是第一次添加执行else
		{
		    // 以下两部保证链表不会断裂
		    // 将当前第一个结点的prev指针，指向结点me
			first.prev = me;
			// 将me的next指针，指向当前第一个结点。
			me.next = first;
		}
		// first结点指向me
		first = me;
		// 链表长度加一
		size++;
	}


	/**
	 * @description: 在链表的最后一个位置添加节点
	 * @author: 田培融
	 * @date: 2019/7/31 10:07
	  * @param me	节点
	 * @return: void
	 */
	public synchronized void addLast(T me)
	{
	    // 如果链表没有值
		if (first == null)
		{
		    // 在第一个位置添加节点
			first = me;
		}
		else//链表中有值
		{

		    //最后一个节点的next指针，指向me
			last.next = me;
			//me的prev指针批向最后一个节点。
			me.prev = last;
		}

		// last指针，指向me
		last = me;
		size++;
	}

	/**
	 * @description: 获取链表中的第一个节点元素
	 * @author: 田培融
	 * @date: 2019/7/31 10:14
	  * @param
	 * @return: T 第一个节点元素
	 */
	public synchronized T getFirst()
	{
		if (log.isDebugEnabled())
		{
			log.debug("return first node");
		}
		return first;
	}

	/**
	 * @description: 获取链表中的最后一个节点元素
	 * @author: 田培融
	 * @date: 2019/7/31 10:14
	  * @param
	 * @return: T 最后一个节点元素
	 */
	public synchronized T getLast()
	{
		if (log.isDebugEnabled())
		{
			log.debug("return last node");
		}
		return last;
	}

	/**
	 * @description: 当指定ln移动到链表第一个节点的位置
	 * @author: 田培融
	 * @date: 2019/7/26 7:43
	  * @param ln 节点
	 * @return: void
	 */
	public synchronized void makeFirst(T ln)
	{

		// ln节点就为第一个节点
		if (ln.prev == null)
		{
			return;
		}

		// 将前一个节点的next指针，指向下一个节点
		ln.prev.next = ln.next;

		// 如果下一个节点为null，表示ln为最后一个节点
		if (ln.next == null)
		{
			//将last指针向当前一个节点。
			last = (T) ln.prev;
			//将last指针指向的节点的next设置为null
			last.next = null;
		}
		else//ln不为最后一个节点
		{
			//将下一个节点的prev，指向前一个节点
			ln.next.prev = ln.prev;
		}
		// 第一个节点的prev 指向ln
		first.prev = ln;
		// ln的next指针，指向第一个节点
		ln.next = first;

		//ln的prev 设置为null
		ln.prev = null;
		// first指向ln
		first = ln;
	}


	/**
	 * @description: 将节点移动到最后一个节点的位置
	 * @author: 田培融
	 * @date: 2019/7/31 13:29
	  * @param ln 节点
	 * @return: void
	 */
	public synchronized void makeLast(T ln)
	{

		//ln节点为最后一个节点
		if (ln.next == null)
		{
			return;
		}


		if (ln.prev != null)
		{
			// 将ln 前一个节点的next指针，指向ln的下一个节点
			ln.prev.next = ln.next;
		}
		else
		{
			first = last;
		}

		if (last != null)
		{
			// 最后一个节点的next指向ln
			last.next = ln;
		}

		// ln的prev 指向最后一个节点
		ln.prev = last;
		// ln的next 设置为null
		ln.next = null;
		//last 指向ln， ln变为了最后一个节点
		last = ln;
	}

	/**
	 * @description: 链表清空所有节点
	 * @author: 田培融
	 * @date: 2019/7/31 13:57
	 * @return: void
	 */
	public synchronized void removeAll()
	{
		for (T me = first; me != null;)
		{
			if (me.prev != null)
			{
				me.prev = null;
			}
			T next = (T) me.next;
			me = next;
		}
		first = last = null;
		size = 0;
	}

	/**
	 * @description: 删除指定节点
	 * @author: 田培融
	 * @date: 2019/7/31 13:58
	  * @param me	节点
	 * @return: boolean
	 */
	public synchronized boolean remove(T me)
	{
		if (log.isDebugEnabled())
		{
			log.debug("remove node");
		}

		if (me.next == null)
		{
			if (me.prev == null)
			{

				if (me == first && me == last)
				{
					first = last = null;
				}
			}
			else
			{
				last = (T) me.prev;
				last.next = null;
				me.prev = null;
			}
		}
		else if (me.prev == null)
		{
			first = (T) me.next;
			first.prev = null;
			me.next = null;
		}
		else
		{
			me.prev.next = me.next;
			me.next.prev = me.prev;
			me.prev = me.next = null;
		}
		size--;

		return true;
	}

	/**
	 * @description: 删除最后一个节点并返回
	 * @author: 田培融
	 * @date: 2019/7/31 13:58
	  * @param
	 * @return: T 最后一个节点
	 */
	public synchronized T removeLast()
	{
		if (log.isDebugEnabled())
		{
			log.debug("remove last node");
		}
		T temp = last;
		if (last != null)
		{
			remove(last);
		}
		return temp;
	}

	// 链表的长度
	public synchronized int size()
	{
		return size;
	}

	//遍历链表的元素
	public synchronized void debugDumpEntries()
	{
		if (log.isDebugEnabled())
		{
			log.debug("dump Entries");
			for (T me = first; me != null; me = (T) me.next)
			{
				log.debug("dump Entries> payload= '" + me.getPayload() + "'");
			}
		}
	}
}
